package com.company.multithreads;

import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.I_Result;

/**
 * 【有序性问题】 程序中代码的执行顺序【玩不来哦！！！难受，有懂得小伙伴评论下，教教我这个菜鸡！！在此谢谢了】
 *     java并发压测工具
 *     Java 在编译时和运行时会对代码进行优化,会导致程序最终的执行顺序不一定就是我们编写代码时的顺序。
 *
 *  @JCStressTest 该注解标记一个类为一个并发测试的类
 *  @Outcome 是描述测试结果，并处理这个结果，该注解有 id、expect、desc 这三个属性。
 *              id 接收结果
 *              expect 是期望处理结果：ACCEPTABLE 表示接受当前结果，ACCEPTABLE 结果不一定会存在；ACCEPTABLE_INTERESTING 和 ACCEPTABLE 差不多，唯一不一样的是，这个结果会在生成的报告中高亮；FORBIDDEN 表示永远不应该出现的结果，若测试过程中有该结果，意味着测试失败； UNKNOWN 没有评分，不使用。
 *  @State  修饰的类必须是 public 的，不能是内部类，但是可以是静态内部类； 修饰的类必须有一个默认构造函数
 *  @Actor  该注解标记的方法会被线程调用；被 @Actor 修饰方法所在的类必须有 @State 或者 @Result注解，被其修饰的方法可以抛出异常，但是抛出异常的话，会引起测试失败。
 *          ，@Actor 标记的每个方法仅由一个特定线程调用，而且每个被 @State 标记的实例仅调用每一个方法。@Actor 修饰的方法之间是没有顺序的，调用是并发执行的。
 *
 *  小结：程序代码在执行过程中的先后顺序，由于Java在编译期以及运行期的优化，导致了代码的执行顺序未必就是开发者编写代码时的顺序。
 */

@JCStressTest
@Outcome(id = {"1", "4"}, expect = Expect.ACCEPTABLE, desc = "ok")
@Outcome(id = "0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "danger")
@State
public class Test03OrderLiness {
    int num = 0;
    boolean ready = false;

    // 线程 1 执行的代码
    @Actor
    public void actor1(I_Result r) {
        if (ready) {
            r.r1 = num + num;
        } else {
            r.r1 = 1;
        }
    }

    // 线程 2 执行的代码
    @Actor
    public void actor2(I_Result r) {
        num = 2;
        ready = true;
    }

//    public static void main(String[] args) {
//        int a = 10;
//        int b = 20;
//    }
}
